﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace ElementClasses
{
    public enum SettingsElType { String, Int, Double, Bool }

    public enum TrySynchronizeResult { SourceDataCanBeReplaced, NeedReWrite }

    /// <summary> Элемент настроек </summary>
    public class SettingsElement
    {
        public SettingsElType Tp;
        public string Name;
        public string FieldName;
        public object DefaultValue;
        public object Value;

        /// <summary> Конструктор </summary>
        /// <param name="Name">Имя поля для редактирования пользователем. Если имя пустое, элемент недоступен для редактирования на странице настроек</param>
        /// <param name="FieldName">Уникальное имя поля в файле</param>
        /// <param name="DefaultValue">Значение по умолчанию</param>
        /// <param name="Tp">Тип значения</param>
        public SettingsElement(string Name, string FieldName, object DefaultValue, SettingsElType Tp)
        {
            this.Name = Name;
            this.FieldName = FieldName;
            this.DefaultValue = DefaultValue;
            this.Value = DefaultValue;
            this.Tp = Tp;
        }
    }

    //public delegate void ElementFunction(Element elm);
    //public delegate void EmptyFunction();

    /// <summary> Апи для подключаемых модулей </summary>
    /*public class eeAPI_Funtions
    {
        /// <summary> Сохранние настроек </summary>
        public Action SaveSettings;
        /// <summary> Сохранние данных на локальный диск </summary>
        //public Action SaveData;

        public eeAPI_Funtions(Action SaveSettings)
        {
            this.SaveSettings = SaveSettings;
            //this.SaveData = SaveData;
        }

    }*/

    public enum ChangeDataEvents {LoadAfterInit, ReWriteFromServer }

    /// <summary> Внелемент. Стартует при старте приложения. </summary>
    public abstract class ExternalElement
    {
        #region *** переменные *************************************

        /// <summary> Уникальное Имя Внелемента</summary>
        public abstract string Name { get; }

        public abstract string MenuName { get; }

        /// <summary>Требуется сохранить измененный элемент. Возводится, когда это нужно. Сбрасывается системой по окончании сохранения
        /// При сохранеии, так же возводится ожидание на синхронизацию с сервером</summary>
        public bool IsSaveData;

        /// <summary> в данный момент элемент редактируется (Синхронизация будет ожидать до окончания редактирования)</summary>
        public bool IsEdit = false;

        #endregion *** переменные *************************************

        public abstract void ChangeSourceData(ChangeDataEvents ChangeDataEvent, byte[] NewSourceData);

        public abstract byte[] GetSourceData();

        /// <summary> кнопка в трее </summary>
        public ToolStripMenuItem NotifyMenuBotton = new ToolStripMenuItem();

        void NotifyMenuBotton_Click(object source, EventArgs e)
        {
            NotifyMenuBotton_Click();
        }

        /// <summary> API функции органайзера для внелемента </summary>
        //public eeAPI_Funtions API_Func;

        // настройки для элемента
        //public List<SettingsElement> SettEl = new List<SettingsElement>();

        #region *** события ***************************************

        /// <summary> инициализация. Событие возникает Сразу после создания, но до загрузки данных </summary>
        public abstract void Init();

        /// <summary> событие возникает при клику меню </summary>
        public abstract void NotifyMenuBotton_Click();

        /// <summary> Попытка синхронизации данных, если на сервере версия новее, а внелемент редактировался (NotActual) (т.е. Скрипт ручной синхронизации)
        /// НУЖНО ТОЛЬКО ЕСЛИ при каких-то изменениях данных это не считается новой версией. 
        /// После синхронизации данные обязательно должны быть идентичны серверным
        /// Возвращает, удачна ли синхронизация. 
        /// Если неудечна (false): внелемент заменяется серверным и вызывается событие ChangeSourceData с ChangeDataEvents.ReWriteFromServer 
        /// Если удачна (тrue): версия внелемента просто обновляется на текущую а внелемент становится актуальным
        /// </summary>
        public virtual TrySynchronizeResult TrySynchronizeNotActual(byte[] ServerSourceData) { return TrySynchronizeResult.SourceDataCanBeReplaced; }

        /// <summary> метод возывается единожды загрузки базы. Сам внелемент создается до загрузки базы </summary>
        public virtual void EndCreate()
        {
            NotifyMenuBotton.Text = MenuName;
            NotifyMenuBotton.Click += new EventHandler(NotifyMenuBotton_Click);
        }

        /// <summary> событие изменения режима гости
        /// Нужно только, если форма постоянна открыта и ей необходимо следить за режимом
        /// Если форма открывается только для редактирования, обычно достаточно только Disabled пункта меню вызова. </summary>
        public virtual void GuestModeChange(bool bGuest) { ;}

        #endregion *** события ***************************************

    }

}
